// ManipulatorWindow.cpp

#include "ManipulatorWindow.h"
#include "SimpleGLUTApplication.h"
#include "ManipulatorGLObject.h"

namespace Voltron
{

	ManipulatorWindow::ManipulatorWindow() : AbstractGLUTWindow()
	{
		DEBUG_PRINT("ManipulatorWindow::ManipulatorWindow() : AbstractGLUTWindow()\n");

		_scene = new GLScene();
		
		objectID = 200;
		picked = -1;
		flag = 0;
		
		lastX=0 , lastY = 0;
		
		transformMode = 0;
		modelMode = 0;
		sceneMode = 0;
		
		light_position = point4( 1.5, 0.5, 2.0, 1.0 );
		material_shininess = 100.0;
		shades = 4;

	
	}

	ManipulatorWindow::ManipulatorWindow(string title,  int windowXpos, int windowYpos, int windowHeight, int windowWidth):
				AbstractGLUTWindow(title, windowXpos, windowYpos, windowHeight, windowWidth)
	{
		ManipulatorWindow();
	}

		
	ManipulatorWindow::~ManipulatorWindow()
	{
		// if data is open file 
			// close file
		// if data matrix is not empty
			// delete it
		// if vertex buffers are not empty
			// delete the
		// if color buffers are not empty
			// delete the color buffers
	}

	
	void ManipulatorWindow::initWindow(string title,  int windowXpos, int windowYpos, int windowHeight, int windowWidth, char *argv[])
	{
		DEBUG_PRINT("initWindow()\n");

		_title = title;
		_windowXpos = windowXpos;
		_windowYpos = windowYpos;
		_windowHeight = windowHeight;
		_windowWidth = windowWidth;
		
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
        glutInitContextVersion(3,2);
        glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);

   		glutInitWindowSize(_windowWidth, _windowHeight);
   		glutInitWindowPosition(_windowXpos, _windowYpos);
        GLuint winID = glutCreateWindow(_title.c_str());

		setID(winID);
		
		glewExperimental = GL_TRUE;
        glewInit();

		DEBUG_PRINT("InitShader()\n");

		phongShaderProgram = InitShader("phong_vshader.glsl", "phong_fshader.glsl");
		toonShaderProgram = InitShader("toon_vshader.glsl", "toon_fshader.glsl");

		shaderprogram = toonShaderProgram;
		
		glUseProgram(shaderprogram);

		DEBUG_PRINT("after InitShader()\n");

		_manipulatorobj = new ManipulatorGLObject(shaderprogram);
		//_scene->addObject((GLObject3D *)_manipulatorobj);

		DEBUG_PRINT("getFileNames()\n");
		objectNames = getFileNames(argv[1]);

		DEBUG_PRINT("init()\n");
		init();

		DEBUG_PRINT("initView()\n");
		initView(argv);

		DEBUG_PRINT("initCallbacks()\n");
		initCallbacks();

		DEBUG_PRINT("createMenu()\n");
		createMenu();

	}

	void ManipulatorWindow::initWindow()
	{
		//initView();

		//initMenu();
	}

	void ManipulatorWindow::initView(char *argv[])
	{
	    model_view = glGetUniformLocation( shaderprogram, "ModelView");
	    projection = glGetUniformLocation( shaderprogram, "Projection");
	    mat4 p;
	
	    if(string(argv[2]) == "O")
	    {
	        p =  Ortho(atof(argv[3]),atof(argv[4]),atof(argv[5]),atof(argv[6]),atof(argv[7]),atof(argv[8]));
	    }
	
	    else if(string(argv[2]) == "P")
	    {
	        p = Perspective(atof(argv[3]),1.0,atof(argv[4]),atof(argv[5]));
	    }
	    else
	    {
	        cout << "Not a valid command" << endl;
	        exit(-1);
	    }
	
		eye = point4( 0, 0, 3, 1.0);
		at = point4( 0, 0, 0, 1.0);
		up = vec4( 0, 2, 0, 0.0);
	
	    view = LookAt( eye, at, up );
	    mv = view;
	
	    glUniformMatrix4fv( model_view, 1, GL_TRUE, mv );
	    glUniformMatrix4fv( projection, 1, GL_TRUE, p );
	    
   		// set no clipping on the viewport, i.e., use the entire window extents
   		glViewport(0, 0, _windowWidth, _windowWidth); 

	    //glClearColor(0.0, 0.0, 0.0, 0.0);
	    glClearColor(1.0, 1.0, 1.0, 0.0);

	    
	}
	
	void ManipulatorWindow::updateProjection(char *argv[],float aspectRatio)
	{
	    projection = glGetUniformLocation( shaderprogram, "Projection");
	
	    if(string(argv[2]) == "O")
	    {
	        p =  Ortho(atof(argv[3])*aspectRatio,atof(argv[4])*aspectRatio,atof(argv[5])*aspectRatio,atof(argv[6])*aspectRatio,atof(argv[7]),atof(argv[8]));
	    }
	
	    else if(string(argv[2]) == "P")
	    {
	        p = Perspective(atof(argv[3]),aspectRatio,atof(argv[4]),atof(argv[5]));
	    }
	    glUniformMatrix4fv( projection, 1, GL_TRUE, p );
	}	

	void ManipulatorWindow::initCallbacks()
	{
		// wire up all the static callbacks to the virtual implementations
		glutReshapeFunc(onReshapeCallback);
		glutDisplayFunc(onDisplayCallback);
		glutKeyboardFunc(onKeyboardCallback);
		glutSpecialFunc(onSpecialCallback);
		glutMouseFunc(onMouseCallback);
		glutMotionFunc(onMotionCallback);       
	}


	void ManipulatorWindow::init()
	{
		//shaderprogram = InitShader("vshader.glsl", "fshader.glsl");
		glUseProgram(shaderprogram);

		// Initialize shader lighting parameters
	    // RAM: No need to change these...we'll learn about the details when we
	    // cover Illumination and Shading
	    color4 light_ambient( 0.0, 0.0, 0.0, 1.0 );
	    color4 light_diffuse( 1.0, 1.0, 1.0, 1.0 );
	    color4 light_specular( 1.0, 1.0, 1.0, 1.0 );
	
	    color4 material_ambient( 1.0, 1.0, 1.0, 1.0 );
	    color4 material_diffuse( 1.0, 0.8, 0.0, 1.0 );
	    color4 material_specular( 0.3, 0.3, 0.3, 1.0 );
	
	    ambient_product = light_ambient * material_ambient;
	    diffuse_product = light_diffuse * material_diffuse;
	    specular_product = light_specular * material_specular;
	
	    glUniform4fv( glGetUniformLocation(shaderprogram, "AmbientProduct"),
			  1, ambient_product );
	    glUniform4fv( glGetUniformLocation(shaderprogram, "DiffuseProduct"),
			  1, diffuse_product );
	    glUniform4fv( glGetUniformLocation(shaderprogram, "SpecularProduct"),
			  1, specular_product );
	
	    glUniform4fv( glGetUniformLocation(shaderprogram, "LightPosition"),
			  1, light_position );
	
	    glUniform1f( glGetUniformLocation(shaderprogram, "Shininess"),
			 material_shininess );
	
	    glEnable( GL_DEPTH_TEST );

	///////////////////////////////////////////////////////////////////////
	//// ^^^ THIS STUFF NEEDS TO BE WRAPPED BETTER
	///////////////////////////////////////////////////////////////////////
	
	    // black background
//	    glClearColor( 0.0, 0.0, 0.0, 0.0 );
	    glClearColor( 1.0, 1.0, 1.0, 0.0 );
	}



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// override all the event virtual members
	void ManipulatorWindow::onReshape(int windowWidth, int windowHeight)
	{
		    glViewport(0,0,windowWidth,windowHeight);
		    //updateProjection(g_argv,width/height);

	}
	
	
	void ManipulatorWindow::onDisplay(void)
	{
	    // clear the window
	    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

		//_manipulatorobj->_visible = true;
		//glUniformMatrix4fv( model_view, 1, GL_TRUE, _manipulatorobj->_model);
		//_manipulatorobj->render();
	
         for (int i=0;i < _scene->_sceneObjects->size();i++)
         {
             if(picked == i)
             {
                (*(_scene->_sceneObjects))[i]->setDrawMode(GL_LINE);
             }
             else
             {
                (*(_scene->_sceneObjects))[i]->setDrawMode(GL_FILL);
             }

            glUniformMatrix4fv( model_view, 1, GL_TRUE, (*(_scene->_sceneObjects))[i]->_model);
            (*(_scene->_sceneObjects))[i]->render();
         }
		//_manipulatorobj->_visible = true;
		//_manipulatorobj->render();
	    glFlush();
	    glutSwapBuffers();
	    glutPostRedisplay();
	}
	
	
	void ManipulatorWindow::onKeyboard(unsigned char key, int x, int y)
	{

	   switch (key) {
	
	    // Quit when ESC is pressed
	    case 27:
			picked = -1;
			_manipulatorobj->_visible = false;
			break;
	    // Quit when ESC is pressed
	    case (int)('q'):
	        exit(EXIT_SUCCESS);
	        break;

		case (int)('1'):
	        loadObjectMenu(1);
	        break;

		case (int)('2'):
	        loadObjectMenu(2);
	        break;

	    }
	    		
	}
	
	void ManipulatorWindow::onSpecial(int key, int x, int y)
	{
	    switch(key)
	    {
		    case GLUT_KEY_UP:
		        if (modelMode++ > 3)
		            modelMode = 0;
		        break;
		
		    case GLUT_KEY_RIGHT:
		        if(shaderprogram == toonShaderProgram)
		        {
		            shades++;
		            glUniform1f( glGetUniformLocation(shaderprogram, "Shades"),
		                        shades );
					cout << "Numshades: " << shades << endl;
		        }
		        break;
		    case GLUT_KEY_LEFT:
		        if(shaderprogram == toonShaderProgram)
		        {
		            shades--;
		            glUniform1f( glGetUniformLocation(shaderprogram, "Shades"),
		                        shades );
					cout << "Numshades: " << shades << endl;
		        }
		        break;
	    }
	}
	
	void ManipulatorWindow::onMouse(int button, int state, int x, int y)
	{
	    printf("Mouse button pressed at %d, %d\n", x, y);
	    lastX = x;
	    lastY = y;
	    mouseDown = (state == GLUT_DOWN);
	
	    GLubyte pixel[4];
	    GLint viewport[4];
	    glGetIntegerv(GL_VIEWPORT,viewport);
	
	    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	    for (int i=0;i < _scene->_sceneObjects->size();i++){
	        (*(_scene->_sceneObjects))[i]->renderSelectionColor();
	    }
	
	    glReadPixels(x,viewport[3] - y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
	    picked = -1;
		_manipulatorobj->_visible = false;
		
	    for (int i=0;i < _scene->_sceneObjects->size();i++){
	        if((*(_scene->_sceneObjects))[i]->isSelected(pixel)){
	            picked = i;
	            _manipulatorobj->_visible = true;

	        }
	    }

	}
	
	void ManipulatorWindow::onMotion(int x, int y)
	{
		if(mouseDown)
	    {

			int dx = lastX - x;
	        int dy = lastY - y;
	
	        for (int i=0;i < _scene->_sceneObjects->size();i++)
	        {
	            switch(transformMode)
	            {
	                case 0:
	                    model = translate(modelMode,dx,dy);
	                    if(picked == i)
	                        (*(_scene->_sceneObjects))[i]->transformModel(model);
	                    break;
	                case 1:
	                    model = rotate(modelMode,dx,dy);
	                    if(picked == i)
	                        (*(_scene->_sceneObjects))[i]->transformModel(model);
	                    break;
	                case 2:
	                    model = scale(modelMode,dx,dy);
			            if(picked == i)
			            {
							    (*(_scene->_sceneObjects))[i]->transformModel(model);
							    _manipulatorobj->transformModel(model);
						}
	                    break;
	                case 3:
	                    model = pan(dx,dy);
	                    (*(_scene->_sceneObjects))[i]->transformModel(model);
	                    break;
	                case 4:
	                    model = dolly(dx,dy);
	                    (*(_scene->_sceneObjects))[i]->transformModel(model);
	                    break;
	                case 5:
	                    model = sceneRotate(sceneMode,dx,dy);
	                    //(*(_scene->_sceneObjects))[i]->transformModel(inverseTranspose(model));
	                    break;
	            }
	        }

	    }

	    lastX = x;
	    lastY = y;		
	}
	
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	// had to put hard static functions in to call the overridden virtual event handlers
	// becase GLUT is a hinkey and require 'C' style function pointers.
	void ManipulatorWindow::onReshapeCallback(int windowWidth, int windowHeight)
	{
		ManipulatorWindowSingleton::Instance()->onReshape(windowWidth, windowHeight);
	}
	
	void ManipulatorWindow::onDisplayCallback(void)
	{
		ManipulatorWindowSingleton::Instance()->onDisplay();
	}
	
	void ManipulatorWindow::onKeyboardCallback(unsigned char key, int x, int y)
	{
		ManipulatorWindowSingleton::Instance()->onKeyboard(key, x, y);
	}
	
	void ManipulatorWindow::onSpecialCallback(int key, int x, int y)
	{
		ManipulatorWindowSingleton::Instance()->onSpecial(key, x, y);
	}
	
	void ManipulatorWindow::onMouseCallback(int button, int state, int x, int y)
	{
		ManipulatorWindowSingleton::Instance()->onMouse(button, state, x, y);
	}
	
	void ManipulatorWindow::onMotionCallback(int x, int y)
	{
		ManipulatorWindowSingleton::Instance()->onMotion(x, y);
	}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	
	//----------------------------------------------------------------------------
	mat4 ManipulatorWindow::translate(int mode, int dx, int dy)
	{
	    mat4 modelTransform;
	    switch(mode){
	        case 0:
	            modelTransform = Translate(-dx * .1,0,0);
	            break;
	        case 1:
	            modelTransform = Translate(0, dy * .1, 0);
	            break;
	        case 2:
	            modelTransform = Translate(0,0,dx * .1);
	            break;
	    }
	    return modelTransform;
	}
	
	//----------------------------------------------------------------------------
	mat4 ManipulatorWindow::rotate(int mode, int dx, int dy)
	{
	    mat4 modelTransform;
	    switch(mode){
	        case 0:
	            modelTransform = RotateX(-dy * .1);
	            break;
	        case 1:
	            modelTransform = RotateY(-dx * .1);
	            break;
	        case 2:
	            modelTransform = RotateZ(-dx * .1);
	            break;
	    }
	    return modelTransform;
	}
	
	//----------------------------------------------------------------------------
	mat4 ManipulatorWindow::scale(int mode, int dx, int dy)
	{
	    mat4 modelTransform;
	    switch(mode){
	        case 0:
	            modelTransform = Scale(1 + (dx * .1),1,1);
	            break;
	        case 1:
	            modelTransform = Scale(1, 1 + (dy * .1), 1);
	            break;
	        case 2:
	            modelTransform = Scale(1, 1, 1+ (dx * .1));
	            break;
	    }
	    return modelTransform;
	}
	
	
	//----------------------------------------------------------------------------
	mat4 ManipulatorWindow::pan(int dx, int dy)
	{
	    mat4 modelTransform;
	    modelTransform = Translate(float(dx) * .1,0,0);
	    return modelTransform;
	}

	//----------------------------------------------------------------------------
	mat4 ManipulatorWindow::sceneRotate(int mode, int dx, int dy)
	{
	    mat4 modelTransform;
	    switch(mode){
	        case 0:
	            modelTransform = RotateX(float(dy) * .1);
	            break;
	        case 1:
	            modelTransform = RotateY(float(dx) * .1);
	            break;
	        case 2:
	            modelTransform = RotateZ(float(dx) * .1);
	            break;
	    }
	    return modelTransform;
	}

	//----------------------------------------------------------------------------
	mat4 ManipulatorWindow::dolly(int dx, int dy)
	{
	    mat4 modelTransform;
	    modelTransform = Translate(0,0,float(-dy) *.1);
	    return modelTransform;
	}


	//----------------------------------------------------------------------------
	void ManipulatorWindow::shadersMenu(int value)
	{
	    if(value == 0)
	    {
			DEBUG_PRINT("Selected Phong Shader\n");
	        shaderprogram = phongShaderProgram;
	        glUseProgram(shaderprogram);
	    }
	    if(value == 1)
	    {
			DEBUG_PRINT("Selected Toon Shader\n");
	        shaderprogram = toonShaderProgram;
	        glUseProgram(shaderprogram);
	        glUniform1f( glGetUniformLocation(shaderprogram, "Shades"),shades);
	    }
        glUniform4fv( glGetUniformLocation(shaderprogram, "AmbientProduct"),
                    1, ambient_product );
        glUniform4fv( glGetUniformLocation(shaderprogram, "DiffuseProduct"),
                    1, diffuse_product );
        glUniform4fv( glGetUniformLocation(shaderprogram, "SpecularProduct"),
                    1, specular_product );
        glUniform4fv( glGetUniformLocation(shaderprogram, "LightPosition"),
                    1, light_position );
        glUniform1f( glGetUniformLocation(shaderprogram, "Shininess"),
                    material_shininess );
        model_view = glGetUniformLocation(shaderprogram, "ModelView");
        projection = glGetUniformLocation(shaderprogram, "Projection");
        glUniformMatrix4fv( model_view, 1, GL_TRUE, mv );
        glUniformMatrix4fv( projection, 1, GL_TRUE, p );
	
	    glutPostRedisplay();
	}

	//----------------------------------------------------------------------------
	void ManipulatorWindow::objectMenu(int value)
	{
	    if(value == 0){
	        exit(0);
	    }
	    if(value == 1){
	        cout << "Object Translation" << endl;
	        transformMode = 0;
	    }
	    if(value == 2){
	        cout << "Object Rotation" << endl;
	        transformMode = 1;
	    }
	    if(value == 3){
	        cout << "Object Scale" << endl;
	        transformMode = 2;
	    }
	    glutPostRedisplay();
	}
	
	//----------------------------------------------------------------------------
	void ManipulatorWindow::sceneMenu(int value)
	{
	    if(value == 0){
	        exit(0);
	    }
	    if(value == 1){
	        cout << "Scene Translation" << endl;
	    }
	    if(value == 2){
	        cout << "Scene Rotation" << endl;
	    }
	    if(value == 3){
	        cout << "Scene Dolly" << endl;
	    }
	    glutPostRedisplay();
	}
	
	//----------------------------------------------------------------------------
	void ManipulatorWindow::sceneRotationMenu(int value)
	{
	    if(value == 0){
	        exit(0);
	    }
	    if(value == 1){
	        cout << "X" << endl;
	    }
	    if(value == 2){
	        cout << "Y" << endl;
	    }
	    if(value == 3){
	        cout << "Z" << endl;
	    }
	    glutPostRedisplay();
	}
	
	//----------------------------------------------------------------------------
	void ManipulatorWindow::mainMenu(int value)
	{
	    if(value == 0){
	        exit(0);
	    }
	    if(value == 1){
	        cout << "Object Transformation" << endl;
	    }
	    if(value == 2){
	        cout << "Scene Transformation" << endl;
	    }
	    glutPostRedisplay();
	}
	
	//----------------------------------------------------------------------------
	//Returns vector of file names
	vector <string> ManipulatorWindow::getFileNames(const string directory)
	{
	    DIR *dir;
	    class dirent *ent;
	    class stat st;
	    vector <string> objNames;
	
	    dir = opendir(directory.c_str());
	    while ((ent = readdir(dir)) != NULL) {
	        const string file_name = ent->d_name;
	        const string full_file_name = directory + "/" + file_name;
	
	        const bool is_file = (S_ISREG(st.st_mode)) != 0;
	        if (file_name[0] == '.')
	                        continue;
	        objNames.push_back(full_file_name);
	    }
	    closedir(dir);
	    return objNames;
	}
	
	//----------------------------------------------------------------------------
	void ManipulatorWindow::populateObjectMenu(vector<string> objNames)
	{
		DEBUG_PRINT("ManipulatorWindow::populateObjectMenu(vector<string> objNames)\n");
	    for(int i = 0; i< objNames.size(); i++)
	    {
	        glutAddMenuEntry(objNames[i].c_str(),i);
			DEBUG_PRINT("%s\n",objNames[i].c_str());
	    }
	
	}
	
	//----------------------------------------------------------------------------
	void ManipulatorWindow::loadObjectMenu(int value)
	{
		DEBUG_PRINT("ManipulatorWindow::loadObjectMenu(int value)\n");

	    globj = new ConcreteGLObject3D();
	    globj->loadGLObjectFromFile(objectNames[value]);
	    _scene->addObject(globj);
	    cout << (*(_scene->_sceneObjects)).size() << endl;
	    (*(_scene->_sceneObjects))[(*(_scene->_sceneObjects)).size()-1]->_selectionColor = vec4(objectID,0,0,1);
	    (*(_scene->_sceneObjects))[(*(_scene->_sceneObjects)).size()-1]->initBuffers(shaderprogram);
	    (*(_scene->_sceneObjects))[(*(_scene->_sceneObjects)).size()-1]->transformModel(view);
	    glUniformMatrix4fv(model_view,1,GL_TRUE,mv);
	    (*(_scene->_sceneObjects))[(*(_scene->_sceneObjects)).size()-1]->render();
	    objectID++;
	    cout << objectNames[value] << endl;
	    glutPostRedisplay();
	    
   		DEBUG_PRINT("after ManipulatorWindow::loadObjectMenu(int value)\n");

	}
	
	//----------------------------------------------------------------------------
	void ManipulatorWindow::createMenu(void)
	{
	    objectSubMenu = glutCreateMenu(objectMenuCallback);
	    glutAddMenuEntry("Translation",1);
	    glutAddMenuEntry("Rotation",2);
	    glutAddMenuEntry("Scale",3);
	
	    sceneRotationSubMenu = glutCreateMenu(sceneRotationMenuCallback);
	    glutAddMenuEntry("X",1);
	    glutAddMenuEntry("Y",2);
	    glutAddMenuEntry("Z",3);
	
	    sceneSubMenu = glutCreateMenu(sceneMenuCallback);
	    glutAddMenuEntry("Translation",1);
	    glutAddSubMenu("Rotation",sceneRotationSubMenu);
	    glutAddMenuEntry("Dolly",3);
	
	    loadObjectsMenu = glutCreateMenu(loadObjectMenuCallback);
	    populateObjectMenu(objectNames);

	    shaderMenu = glutCreateMenu(shadersMenuCallback);
	    glutAddMenuEntry("Phong",0);
	    glutAddMenuEntry("Cell Shader",1);
	
	    glutCreateMenu(mainMenuCallback);
	    glutAddSubMenu("Object Transformation",objectSubMenu);
	    glutAddSubMenu("Scene Transformation",sceneSubMenu);
	    glutAddSubMenu("Load Objects",loadObjectsMenu);
		glutAddSubMenu("Shaders",shaderMenu);
	    glutAttachMenu(GLUT_RIGHT_BUTTON);
	}
		 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	// had to put hard static functions for menues 
	// becase GLUT is a hinkey and require 'C' style function pointers.

	//----------------------------------------------------------------------------
	void ManipulatorWindow::loadObjectMenuCallback(int value)
	{
		ManipulatorWindowSingleton::Instance()->loadObjectMenu(value);
	}

	//----------------------------------------------------------------------------
	void ManipulatorWindow::objectMenuCallback(int value)
	{
		ManipulatorWindowSingleton::Instance()->objectMenu(value);
	}
	
	//----------------------------------------------------------------------------
	void ManipulatorWindow::shadersMenuCallback(int value)
	{
		ManipulatorWindowSingleton::Instance()->shadersMenu(value);
	}
	
	//----------------------------------------------------------------------------
	void ManipulatorWindow::sceneMenuCallback(int value)
	{
		ManipulatorWindowSingleton::Instance()->sceneMenu(value);
	}
	
	//----------------------------------------------------------------------------
	void ManipulatorWindow::sceneRotationMenuCallback(int value)
	{
		ManipulatorWindowSingleton::Instance()->sceneRotationMenu(value);
	}
	
	//----------------------------------------------------------------------------
	void ManipulatorWindow::mainMenuCallback(int value)
	{
		ManipulatorWindowSingleton::Instance()->mainMenu(value);
	}
	


}
